(function () {
  const noop = () => { debugger }

  class H5Result {
    constructor (data, errMsg, code) {
      this.data = data
      this.code = code

      if (errMsg) {
        if (code === '200') {
          code = '500'
        }

        this.err = new Error(errMsg)
      }
    }
  }

  const sendPostMessage = (module, method, params) => {
    const frames = document.getElementsByTagName('iframe')
    for (let k = 0; k < frames.length; k++) {
      const iframe = frames[k]
      const ispost = iframe.getAttribute('isPost')

      // console.log('------------------------------h5-post', k, method, frames[k])
      if (ispost === 'true') {
        iframe.contentWindow.postMessage({ module, method, params }, '*')
      }
    }
  }

  window.$twh5 = {
    app: {
      login: noop,
      stopTeach: noop,
      stopStudentTeach: noop,
      uploadDir: noop
    },

    basic: {
      // 上传文件完成
      uploadfileComplete: noop,
      // 选择文件完成
      UploadSelectFileComplete: noop,
      // PC劫持前端input选择文件进行文件MD5
      uploadSelectFileCompleteByMd5: noop,
      // 断点续传文件上传成功
      uploadFileCompletedByBreakpoint: noop,
      // 截屏完成
      screenCaptureComplete: noop
    },

    ppt: {
      go: noop,
      nextPage: noop,
      prevPage: noop,
      teaching: noop,
      edit: noop,
      editProcess: noop,
      init: noop,
      showThumbs: noop
    },

    paint: {
      toggle: noop,
      open: noop,
      pen: noop,
      close: noop,
      addIcon: noop,
      clear: noop,
      study: noop,
      bkImg: noop,
      recog: noop,
      addImg: noop,
      cursor: noop
    },
    ggb: {
      saveMathFunc: noop,
      loadMathFunc: noop
    },
    writePad: {
      answer: noop,
      responderResult: noop
    },
    device: {
      onlineStudentChanged: noop
    },
    teach: {
      teachStatusChanged: noop
    },
    message: {
      receive: noop,
      sendws: noop
    },
    callnames: {
      getOnlineStudents: noop
    },
    answerMachine: {
      answer: noop,
      responderResult: noop
    },
    studentWork: {
      getLastWorkPictureSavePath: noop,
      selectWorkPictureSavePath: noop,
      saveWorkPicture: noop,
      startRecordAudio: noop,
      stopRecordAudio: noop
    },

    // 活动最小化 恢复窗口
    activities: {
      restore: noop
    },

    // 电子书
    book: {
      isExistCallback: noop,
      downloadBookCallback: noop,
      getBookPageCallback: noop
    },

    /**
    * 功能: 生成函数的执行结果，为方便扩展统一处理返回值逻辑
    * @param {any} data 函数的执行结果
    * @param {Error} errMsg 错误信息
    * @param {String} code 执行代码，默认'200'-成功，'500'-失败
    * @return {Type} 返回值描述
    */
    createResult (data = '', errMsg, code = '200') {
      const result = new H5Result(data, errMsg, code)
      return result
    },

    /**
    * 功能: 开放给pc端的统一调用h5方法的函数
    * @param {String} path h5方法路径(module.method)，如：'app.login'
    * @param {Object} params pc客户端传给h5方法的参数对象，无参数时可省略
    */
    run (path, params = '{}') {
      const [module, method] = path.split('.')
      let errMsg = ''
      let code = ''

      try {
        params = params.replace(new RegExp(/\\/g), '\\\\')
        params = JSON.parse(params)
      } catch {
        code = '500'
        errMsg = 'params参数类型错误'
      }

      if (!module || !method) {
        code = '404'
        errMsg = '未指定H5模块或方法'
      }

      if (typeof params !== 'object') {
        code = '500'
        errMsg = 'params参数类型错误'
      }

      if (this[module][method] === noop) {
        code = '404'
        errMsg = `${module}方法未定义`
      }

      sendPostMessage(module, method, params)
      if (errMsg) {
        /* eslint-disable */
        return Promise.reject(this.createResult('', code, errMsg))
      } else {
        const result = this[module][method](params)

        // 当执行结果未返回值时，默认为执行成功
        if (result === undefined) {
          return Promise.resolve(this.createResult())
        } else if (result instanceof H5Result) {
          return Promise.resolve(result)
        } else if (result instanceof Promise) {
          return result
        } else {
          if (import.meta.env.NODE_ENV === 'development') {
            console.err('PC端调用H5的返回值，必须用window.$twh5.createResult方法生成')
          }
        }
      }
    }
  }
})()
